﻿namespace FiftyOne
{
    using FiftyOne.Foundation.Mobile.Configuration;
    using System;
    using System.Diagnostics;
    using System.Security;

    internal class EventLog : FiftyOne.Log
    {
        private static FiftyOne.EventLog _instance = null;
        private string _logFile = null;
        private static int _logLevel = -1;
        private static int _processId = -1;
        private static object _sync = new object();

        internal static void Debug(Exception ex)
        {
            if (IsDebug)
            {
                Write("Debug", ex.Message);
                Write("Debug", ex.StackTrace);
                if (ex.InnerException != null)
                {
                    Debug(ex.InnerException);
                }
            }
        }

        internal static void Debug(string message)
        {
            if (IsDebug)
            {
                Write("Debug", message);
            }
        }

        internal static void Fatal(Exception ex)
        {
            if (IsFatal)
            {
                Write("Fatal", ex.Message);
                Write("Fatal", ex.StackTrace);
                if (ex.InnerException != null)
                {
                    Fatal(ex.InnerException);
                }
            }
        }

        internal static void Fatal(string message)
        {
            if (IsFatal)
            {
                Write("Fatal", message);
            }
        }

        private static int GetProcessId()
        {
            return Process.GetCurrentProcess().Id;
        }

        internal static void Info(Exception ex)
        {
            if (IsInfo)
            {
                Write("Info", ex.Message);
                Write("Info", ex.StackTrace);
                if (ex.InnerException != null)
                {
                    Info(ex.InnerException);
                }
            }
        }

        internal static void Info(string message)
        {
            if (IsInfo)
            {
                Write("Info", message);
            }
        }

        internal static void Warn(Exception ex)
        {
            if (IsWarn)
            {
                Write("Warn", ex.Message);
                Write("Warn", ex.StackTrace);
                if (ex.InnerException != null)
                {
                    Warn(ex.InnerException);
                }
            }
        }

        internal static void Warn(string message)
        {
            if (IsWarn)
            {
                Write("Warn", message);
            }
        }

        protected internal static void Write(string level, string message)
        {
            Instance.Write(string.Format("{0:s} - {1} - {2} - {3}", new object[] { DateTime.UtcNow, ProcessId, level, message }));
        }

        protected internal static FiftyOne.EventLog Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_sync)
                    {
                        if (_instance == null)
                        {
                            _instance = new FiftyOne.EventLog();
                        }
                    }
                }
                return _instance;
            }
        }

        internal static bool IsDebug
        {
            get
            {
                return (LogLevel >= 4);
            }
        }

        internal static bool IsFatal
        {
            get
            {
                return (LogLevel >= 1);
            }
        }

        internal static bool IsInfo
        {
            get
            {
                return (LogLevel >= 3);
            }
        }

        internal static bool IsWarn
        {
            get
            {
                return (LogLevel >= 2);
            }
        }

        protected override string LogFile
        {
            get
            {
                if (this._logFile == null)
                {
                    lock (_sync)
                    {
                        if ((this._logFile == null) && ((Manager.Log != null) && Manager.Log.Enabled))
                        {
                            this._logFile = Support.GetFilePath(Manager.Log.LogFile);
                        }
                    }
                }
                return this._logFile;
            }
        }

        private static int LogLevel
        {
            get
            {
                if (_logLevel == -1)
                {
                    lock (_sync)
                    {
                        if (((_logLevel == -1) && (Manager.Log != null)) && Manager.Log.Enabled)
                        {
                            string logLevel = Manager.Log.LogLevel;
                            if (logLevel == null)
                            {
                                goto Label_00AA;
                            }
                            if (!(logLevel == "Debug"))
                            {
                                if (logLevel == "Info")
                                {
                                    goto Label_0092;
                                }
                                if (logLevel == "Warn")
                                {
                                    goto Label_009A;
                                }
                                if (logLevel == "Fatal")
                                {
                                    goto Label_00A2;
                                }
                                goto Label_00AA;
                            }
                            _logLevel = 4;
                        }
                        goto Label_00C0;
                    Label_0092:
                        _logLevel = 3;
                        goto Label_00C0;
                    Label_009A:
                        _logLevel = 2;
                        goto Label_00C0;
                    Label_00A2:
                        _logLevel = 1;
                        goto Label_00C0;
                    Label_00AA:
                        _logLevel = 0;
                    }
                }
            Label_00C0:
                return _logLevel;
            }
        }

        private static int ProcessId
        {
            get
            {
                if (_processId == -1)
                {
                    lock (_sync)
                    {
                        if (_processId == -1)
                        {
                            try
                            {
                                _processId = GetProcessId();
                            }
                            catch (SecurityException)
                            {
                                _processId = 0;
                            }
                        }
                    }
                }
                return _processId;
            }
        }
    }
}

